using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Plugin;
using TencentCloudOcrPlugin.Ocr;
using TencentCloudOcrPlugin.Resources;

namespace TencentCloudOcrPlugin
{
    [Icon("pack://application:,,,/TencentCloudOcrPlugin;component/Resources/Icon.png")]
    [Designer("TencentCloudOcrPlugin.Designer.TencentCloudOcrPluginServerCommandDesigner, TencentCloudOcrPlugin")]
    public class TencentCloudOcrPluginServerCommand : Command, ICommandExecutableInServerSideAsync,
        IServerCommandParamGenerator
    {
        [Required]
        [FormulaProperty]
        [DisplayName("Secret Id")]
        [Description("用于标识 API 调用者身份，可以简单类比为用户名，可在云 API 密钥控制台页面申请或查看。")]
        public object SecretId { get; set; }

        [Required]
        [FormulaProperty]
        [DisplayName("Secret Key")]
        [Description("用于验证 API 调用者的身份，可以简单类比为密码，可在云 API 密钥控制台页面申请或查看。")]
        public object SecretKey { get; set; }

        [Required] [DisplayName("操作类型")] public TencentCloudApiOperationType OperationType { get; set; }

        [FlatObjectProperty]
        [DisplayName("参数设置...")]
        public TencentCloudApiPropertyBase OperationParams { get; set; } = new OcrBusinessCardProperties();

        [DisplayName("保存识别结果到变量")] public string ReturnParam { get; set; }

        public async Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext)
        {
            ExecuteResult executeResult;
            try
            {
                var jObject = await GetResult(dataContext);
                dataContext.Parameters[ReturnParam] = jObject;
                executeResult = new ExecuteResult();
            }
            catch (ArgumentNullException ex)
            {
                executeResult = new ExecuteResult
                {
                    ErrCode = 101,
                    Message = ex.Message,
                    AllowWriteResultToResponse = true
                };
            }
            catch (ArgumentException ex)
            {
                executeResult = new ExecuteResult
                {
                    ErrCode = 201,
                    Message = ex.Message,
                    AllowWriteResultToResponse = true
                };
            }
            catch (InvalidOperationException ex)
            {
                executeResult = new ExecuteResult
                {
                    ErrCode = 301,
                    Message = ex.Message,
                    AllowWriteResultToResponse = true
                };
            }
            catch (System.Exception ex)
            {
                executeResult = new ExecuteResult
                {
                    ErrCode = 500,
                    Message = ex.Message,
                    AllowWriteResultToResponse = true
                };
            }

            return executeResult;
        }

        private async Task<Dictionary<string, object>> GetResult(IServerCommandExecuteContext dataContext)
        {
            var clientConfig = new TencentCloudApiClientConfig();
            var secretIdObj = await dataContext.EvaluateFormulaAsync(SecretId);
            var secretKeyObj = await dataContext.EvaluateFormulaAsync(SecretKey);

            var secretId = secretIdObj?.ToString();
            var secretKey = secretKeyObj?.ToString();
            clientConfig.SecretId = secretId;
            clientConfig.SecretKey = secretKey;
            clientConfig.Region = OperationParams.advancedSettings.Region;

            var action = TencentCloudApiActionFactory.GetAction(OperationType);
            var properties = (await dataContext.EvaluateFormulaAsync(OperationParams)) as TencentCloudApiPropertyBase;

            return await action.RunAsync(clientConfig, dataContext, properties);
        }

        public override string ToString()
        {
            return "腾讯云OCR";
        }

        public IEnumerable<GenerateParam> GetGenerateParams()
        {
            if (!string.IsNullOrEmpty(ReturnParam))
            {
                yield return new GenerateNormalParam
                {
                    ParamName = ReturnParam
                };
                var action = TencentCloudApiActionFactory.GetAction(this.OperationType);
                if (action.IsListParam(OperationParams))
                {
                    yield return new GenerateListParam
                    {
                        ParamName = ReturnParam,
                        ItemProperties = action.GetParamList(this.OperationParams)
                    };
                }
                else
                {
                    yield return new GenerateObjectParam
                    {
                        ParamName = ReturnParam,
                        SubProperties = action.GetParamList(OperationParams),
                        SubPropertiesDescription = action.GetParamDescription(OperationParams)
                    };
                }
            }
        }

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }
    }
}